﻿
using System;
using System.Collections.Generic;

namespace IFramework
{
    public class Controller : IController
	{
        protected IView view;                             //IView 的引用
        protected IDictionary<string, Type> commandMap;   //Command 类引用的（通知名）映射
        protected static volatile IController instance;   //接口实例
        protected readonly object syncRoot = new object();//锁对象
        protected static readonly object staticSyncRoot = new object();//静态锁

		protected Controller()
		{
			commandMap = new Dictionary<string, Type>();
			InitializeController();                         //初始化
		}
        static Controller() {}
        public static IController Instance
        {
            get
            {
                if (instance == null)
                {
                    lock (staticSyncRoot)
                    {
                        if (instance == null) instance = new Controller();
                    }
                }
                return instance;
            }
        }

        protected virtual void InitializeController()
        {
            view = View.Instance;
        }

		public virtual void ExecuteCommand(INotification note)
		{
			Type commandType = null;
			lock (syncRoot)
			{
				if (!commandMap.ContainsKey(note.Name)) return;
				commandType = commandMap[note.Name];
			}
			object commandInstance = Activator.CreateInstance(commandType);
			if (commandInstance is ICommand)
			{
				((ICommand) commandInstance).Execute(note);
			}
		}
		public virtual void RegisterCommand(string notificationName, Type commandType)
		{
			lock (syncRoot)
			{
				if (!commandMap.ContainsKey(notificationName))
				{
					view.RegisterObserver(notificationName, new Observer("executeCommand", this));
				}
				commandMap[notificationName] = commandType;
			}
		}

		public virtual bool HasCommand(string notificationName)
		{
			lock (syncRoot)
			{
				return commandMap.ContainsKey(notificationName);
			}
		}
		public virtual void RemoveCommand(string notificationName)
		{
			lock (syncRoot)
			{
				if (commandMap.ContainsKey(notificationName))
				{
					view.RemoveObserver(notificationName, this);
					commandMap.Remove(notificationName);
				}
			}
		}
	}
}
